package com.jz.netthings.netty.decode;

import com.jz.netthings.netty.protocol.bean.ZxdcLoginPacket;
import com.jz.netthings.netty.support.Attributes;
import com.jz.netthings.netty.utils.NettyMsgHelper;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.util.CharsetUtil;

import java.util.List;

public class NettyZxdcNewDecoder extends ByteToMessageDecoder {

//    private static final int LOGIN_PACKET_LEN = 4 + 4 + 4 + 4 + 3 + 4 + 1 + 4 + 1;//单采机登录请求包的长度  29 个长度：消息头 + 连接客户端类型 + 数据格式 + 应用编码的长度 + ...
//    private static final int MSG_PACKET_LEN = 4 + 4;//单采机其他消息包的基本  8 个长度 ：消息头 + 消息长度

//    private static final int LOGIN_PACKET_LEN = 4 + 4 + 4 + 4 + 8 + 4 + 6 + 4 + 1;//单采机登录请求包的长度  39 个长度：消息头 + 连接客户端类型 + 数据格式 + 应用编码的长度 + ...
//    private static final int MSG_PACKET_LEN = 4 + 4;//单采机其他消息包的基本  8 个长度 ：消息头 + 消息长度

    private int LOGIN_PACKET_LEN = 0;
    private int MSG_PACKET_LEN = 0;

//    public NettyZxdcNewDecoder(){ }

    public NettyZxdcNewDecoder(int loginPacketLen,int msgPacketLen){
        this.LOGIN_PACKET_LEN = loginPacketLen;
        this.MSG_PACKET_LEN = msgPacketLen;
    }

    //记录上次未读完的字节
    private ByteBuf tempMessage = Unpooled.buffer();

    @Override
    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception {

//        System.out.println("包长度："+byteBuf.readableBytes());
//        System.out.println("内容：【"+byteBuf.toString(CharsetUtil.US_ASCII)+"】");

        if (tempMessage.readableBytes() > 0){

//            System.out.println("加上上次没有读完的内容：【"+tempMessage.toString(CharsetUtil.US_ASCII)+"】");
            tempMessage.writeBytes(byteBuf);
            byteBuf = tempMessage;
            tempMessage.clear();
        }

        if (byteBuf.readableBytes() < MSG_PACKET_LEN){
            //半包
            return;
        }

        //把当前的读指针保存起来
        byteBuf.markReaderIndex();
        // 获取消息头
        int res_code = -1;
        boolean flag = false;

        while(byteBuf.readableBytes() >= 4){
            res_code = byteBuf.readInt();
//            System.out.println("读取到的 res_code：["+res_code+"]");

            if(res_code == Attributes.LOGIN_RES_CODE || res_code ==  Attributes.MSG_RES_CODE){
                flag = true;
                break;
            }
        }

        if (!flag){
            //没有读到消息头
            byteBuf.resetReaderIndex();
            return;
        }

        if(res_code == Attributes.LOGIN_RES_CODE){
           //是登录消息
            if (byteBuf.readableBytes() >= (LOGIN_PACKET_LEN - 4)){
                ZxdcLoginPacket loginPacket = NettyMsgHelper.buildRequestLoginPacket(res_code, byteBuf);
                list.add(loginPacket);
                if (byteBuf.readableBytes() > 0){
                    //证明后面还有数据
                    tempMessage = Unpooled.buffer(byteBuf.readableBytes());
                    byteBuf.readBytes(tempMessage, byteBuf.readableBytes());
                }
                byteBuf.resetReaderIndex();
            }else{
                //后面数据不够，继续等待
                return;
            }
        }else if(res_code ==  Attributes.MSG_RES_CODE){
            //是其他消息
            if (byteBuf.readableBytes() < 4) {
                //证明消息头后面的消息长度都不够
                byteBuf.resetReaderIndex();
                return;
            }else {
                int length = byteBuf.readInt();//消息长度

                if(byteBuf.readableBytes() >= length){
                    byte[] data = new byte[length];
                    byteBuf.readBytes(data);
                    list.add(data);
                    if (byteBuf.readableBytes() > 0){
                        //证明后面还有数据
                        tempMessage = Unpooled.buffer(byteBuf.readableBytes());
                        byteBuf.readBytes(tempMessage, byteBuf.readableBytes());
                    }
                    byteBuf.resetReaderIndex();
                }else{
                    //后面的数据长度没有达到消息长度
                    byteBuf.resetReaderIndex();
                    return;
                }
            }
        }
        byteBuf.skipBytes(byteBuf.readableBytes());


    }
}
